package main

import (
	"fmt"
	"bufio"
	"encoding/binary"
)

type Proto struct {
	Lenght int32
	Ver int8
	Cmd int8
	HeaderLenght int32
	Header []byte
	Data []byte
}
func NewPingProto() *Proto{
	return &Proto{Ver:1,Cmd:HEARTBEAT}
}
func NewPushProto() *Proto{
	return &Proto{Ver:1,Cmd:MSG}
}
func (p *Proto)SetData(bytes []byte) {
	p.Data = bytes
	p.Lenght = int32(len(bytes))
}
func (p *Proto)SetHeader(bytes []byte) {
	p.Header = bytes
	p.HeaderLenght = int32(len(bytes))
}
func (p *Proto)ReadTcp(rd *bufio.Reader) (*Proto,error)  {
	if err := binary.Read(rd,binary.BigEndian,&p.Lenght);err != nil{
		fmt.Println("ReadTCP() Lenght  fail =>",err)
		return nil,err
	}
	//fmt.Println("p.Lenght :",p.Lenght)
	if err := binary.Read(rd,binary.BigEndian,&p.Ver);err != nil{
		fmt.Println("ReadTCP() Ver fail =>",err)
		return nil,err
	}
	//fmt.Println("p.Ver :",p.Ver)

	if err := binary.Read(rd,binary.BigEndian,&p.Cmd);err != nil{
		fmt.Println("ReadTCP() Cmd fail =>",err)
		return nil,err
	}
	//fmt.Println("p.Cmd :",p.Cmd)

	if err := binary.Read(rd,binary.BigEndian,&p.HeaderLenght);err != nil{
		fmt.Println("ReadTCP() Key fail =>",err)
		return nil,err
	}
	//fmt.Println("p.HeaderLenght :",p.HeaderLenght)

	p.Header = make([]byte,p.HeaderLenght)
	if err := binary.Read(rd,binary.BigEndian,&p.Header);err != nil{
		fmt.Println("ReadTCP() Key fail =>",err)
		return nil,err
	}
	//fmt.Println("p.Header :",string(p.Header))

	p.Data = make([]byte,p.Lenght)
	if err := binary.Read(rd,binary.BigEndian,&p.Data);err != nil{
		fmt.Println("ReadTCP() Data fail =>",err)
		return nil,err
	}
	//fmt.Println("p.Data :",string(p.Data))


	return p,nil
}


func (p *Proto)WriteTcp(rd *bufio.Writer) (*Proto,error)  {
	if err := binary.Write(rd,binary.BigEndian,p.Lenght);err != nil{
		fmt.Println("WriteTcp() Lenght  fail =>",err)
		return nil,err
	}
	if err := binary.Write(rd,binary.BigEndian,p.Ver);err != nil{
		fmt.Println("WriteTcp() Ver fail =>",err)
		return nil,err
	}
	if err := binary.Write(rd,binary.BigEndian,p.Cmd);err != nil{
		fmt.Println("WriteTcp() Cmd fail =>",err)
		return nil,err
	}
	if err := binary.Write(rd,binary.BigEndian,&p.HeaderLenght);err != nil{
		fmt.Println("WriteTcp() HeaderLenght fail =>",err)
		return nil,err
	}
	if err := binary.Write(rd,binary.BigEndian,&p.Header);err != nil{
		fmt.Println("WriteTcp() Header fail =>",err)
		return nil,err
	}
	if err := binary.Write(rd,binary.BigEndian,p.Data);err != nil{
		fmt.Println("WriteTcp() Data fail =>",err)
		return nil,err
	}
	rd.Flush()
	return p,nil
}
